﻿using Admin.NET.Application.Entity.Hr;
using Admin.NET.Core.Service;
using Furion.DatabaseAccessor;
using Furion.FriendlyException;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;

public class EmployeeService : IDynamicApiController, ITransient
{
    private readonly UserManager _userManager;
    private readonly SqlSugarRepository<Employee> _employeeRep;
    private readonly SysOrgService _sysOrgService;
    private readonly EmployeeExtOrgService _employeeExtOrgService;

    public EmployeeService(UserManager userManager,
        SqlSugarRepository<Employee> sysEmployeeRep,
        SysOrgService sysOrgService,
        EmployeeExtOrgService employeeExtOrgService,
        SysUserRoleService sysUserRoleService,
        SysConfigService sysConfigService)
    {
        _userManager = userManager;
        _employeeRep = sysEmployeeRep;
        _sysOrgService = sysOrgService;
        _employeeExtOrgService = employeeExtOrgService;
    }


    /// <summary>
    /// 获取员工分页列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("获取员工分页列表")]
    public async Task<SqlSugarPagedList<Employee>> Page(PageEmployeeInput input)
    {
        var orgList = input.OrgId > 0 ? await _sysOrgService.GetChildIdListWithSelfById(input.OrgId) :
            _userManager.SuperAdmin ? null : await _sysOrgService.GetUserOrgIdList(); // 各管理员只能看到自己机构下的员工列表

        var result= await _employeeRep.AsQueryable()
            .LeftJoin<SysOrg>((el,org) => el.OrgId.Equals(org.Id))
            .LeftJoin<SysPos>((el,org,pos)=>el.PosId.Equals(pos.Id))
            .Where((el, org, pos) => el.AccountType != AccountTypeEnum.SuperAdmin)
            .WhereIF(orgList != null, (el, org, pos) => orgList.Contains(el.OrgId)) 
            .WhereIF(!string.IsNullOrWhiteSpace(input.RealName), (el, org, pos) => el.RealName.Contains(input.RealName))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Phone), (el, org, pos) => el.Phone.Contains(input.Phone))
            .WhereIF(!string.IsNullOrWhiteSpace(input.JobNum), (el, org, pos) => el.JobNum.Contains(input.JobNum))
            .Select((el, org, pos) => new Employee()
            {
                AccountType = el.AccountType,
                Address = el.Address,
                Status = el.Status,
                SysOrg = org,
                Age = el.Age,
                OrgId = org.Id,
                Avatar = el.Avatar,
                Birthday = el.Birthday,
                CardType = el.CardType,
                College = el.College,
                CreatedUserName = el.CreatedUserName,
                CreateTime = el.CreateTime,
                CreateUserId = el.CreateUserId,
                CultureLevel = el.CultureLevel,
                Email = el.Email,
                EmergencyAddress = el.EmergencyAddress,
                EmergencyContact = el.EmergencyContact,
                EmergencyPhone = el.EmergencyPhone,
                Expertise = el.Expertise,
                Id = el.Id,
                IdCardNum = el.IdCardNum,
                Introduction = el.Introduction,
                IsDelete = el.IsDelete,
                JobNum = el.JobNum,
                JoinDate = el.JoinDate,
                Nation = el.Nation,
                NickName = el.NickName,
                Office = el.Office,
                OfficePhone = el.OfficePhone,
                OfficeZone = el.OfficeZone,
                OrderNo = el.OrderNo,
                Phone = el.Phone,
                PoliticalOutlook = el.PoliticalOutlook,
                PosId = el.PosId,
                PosLevel = el.PosLevel,
                PosTitle = pos.Name,
                RealName = el.RealName,
                Remark = el.Remark,
                Sex = el.Sex,
                Signature = el.Signature,
                SysPos = el.SysPos,
                TenantId = el.TenantId,
                UpdatedUserName = el.UpdatedUserName,
                UpdateTime = el.UpdateTime,
                UpdateUserId = el.UpdateUserId,
            })
            .OrderBuilder(input)
            .ToPagedListAsync(input.Page, input.PageSize);
        return result;
    }

    /// <summary>
    /// 增加员工
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [UnitOfWork]
    [ApiDescriptionSettings(Name = "Add"), HttpPost]
    [DisplayName("增加员工")]
    public async Task AddUser(AddEmployeeInput input)
    {
        var isExist = await _employeeRep.AsQueryable().Filter(null, true).AnyAsync(u => u.JobNum == input.JobNum);
        if (isExist) throw Oops.Oh(ErrorCodeEnum.D1003); 

        var employee = input.Adapt<Employee>(); 
        var newUser = await _employeeRep.AsInsertable(employee).ExecuteReturnEntityAsync();
        input.Id = newUser.Id;
        await UpdateRoleAndExtOrg(input);
    }

    /// <summary>
    /// 更新角色和扩展机构
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    private async Task UpdateRoleAndExtOrg(AddEmployeeInput input)
    {  
        await _employeeExtOrgService.UpdateUserExtOrg(input.Id, input.ExtOrgIdList);
    }

    /// <summary>
    /// 更新员工
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [UnitOfWork]
    [ApiDescriptionSettings(Name = "Update"), HttpPost]
    [DisplayName("更新员工")]
    public async Task UpdateUser(UpdateEmployeeInput input)
    {
        var isExist = await _employeeRep.AsQueryable().Filter(null, true).AnyAsync(u => u.JobNum == input.JobNum && u.Id != input.Id);
        if (isExist) throw Oops.Oh(ErrorCodeEnum.D1003);

        await _employeeRep.AsUpdateable(input.Adapt<Employee>()).IgnoreColumns(true)
            .IgnoreColumns(u => new { u.Status }).ExecuteCommandAsync();

        await UpdateRoleAndExtOrg(input);
    }

    /// <summary>
    /// 删除员工
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [UnitOfWork]
    [ApiDescriptionSettings(Name = "Delete"), HttpPost]
    [DisplayName("删除员工")]
    public async Task DeleteUser(DeleteUserInput input)
    {
        var user = await _employeeRep.GetFirstAsync(u => u.Id == input.Id);
        if (user == null)
            throw Oops.Oh(ErrorCodeEnum.D1002);
        if (user.AccountType == AccountTypeEnum.SuperAdmin)
            throw Oops.Oh(ErrorCodeEnum.D1014);
        if (user.Id == _userManager.UserId)
            throw Oops.Oh(ErrorCodeEnum.D1001);

        await _employeeRep.DeleteAsync(user); 

        // 删除员工扩展机构
        await _employeeExtOrgService.DeleteUserExtOrgByUserId(input.Id);
    }

    /// <summary>
    /// 查看员工基本信息
    /// </summary>
    /// <returns></returns>
    [DisplayName("查看员工基本信息")]
    public async Task<Employee> GetBaseInfo()
    {
        return await _employeeRep.GetFirstAsync(u => u.Id == _userManager.UserId);
    }

    /// <summary>
    /// 获取员工扩展机构集合
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    [DisplayName("获取员工扩展机构集合")]
    public async Task<List<EmployeeExtOrg>> GetOwnExtOrgList(long userId)
    {
        return await _employeeExtOrgService.GetUserExtOrgList(userId);
    }
}
